package medOffice;

import java.util.Calendar;
import java.util.GregorianCalendar;

import medOffice.Enuns.Sexo;


/**
 * Classe que implementa uma Pessoa
 * 
 * @author Ana Clara Lacerda de Siqueira - anacls@lcc.ufcg.edu.br
 * @version 1.0 - 03/12/2009
 * 
 */
public class Pessoa {


	private String nome, cpf, telefone, email, endereco;
	private Sexo sexo;
	private Calendar dataDeNascimento;
	private int idade;
	
	/**
     * Construtor default da classe.
     */
	public Pessoa() {
		
	}
	
	/**
     * Construtor apenas com o nome
     * @param String nome
     * @throws Exception caso nao passe nos testes do verificador.
     */
	public Pessoa(String nome) throws Exception {
		setNome(nome);
	}
	
	/**
	 * Construtor da classe Pessoa
	 * 
	 * @param String
	 *            Nome da Pessoa
	 * @param String
	 *            CPF da Pessoa
	 * @throws Exception
	 *             Caso o nome ou cpf seja invalido
	 */
	public Pessoa(String nome, String cpf) throws Exception {
		setNome(nome);
		setCPF(cpf);
	}
	
	/**
	 * Metodo acessador que resgata o nome da pessoa.
	 * @return String nome da pessoa
	 */
	public String getNome() {
		return nome;
	}

	/**
	 * Metodo modificador que seta o nome da Pessoa
	 * 
	 * @param String 
	 *            Novo nome
	 * @throws Exception
	 *             Caso o novo nome seja invalido
	 */
	public void setNome(String nome) throws Exception {
		if (Verificador.verificaNome(nome))
			this.nome = nome;
		else
			throw new Exception("Nome invalido");
	}
	
	/**
	 * Metodo acessador que retorna o cpf de uma pessoa.
	 * @return String cpf da pessoa
	 */
	public String getCPF() {
		return cpf;
	}

	/**
	 * Metodo modificador que seta o CPF da Pessoa
	 * 
	 * @param String
	 *            Novo cpf da pessoa
	 * @return boolean true caso tenha sido atualizado, false caso contrario
	 */
	public void setCPF(String cpf) throws Exception{
		if (!(Verificador.verificaCpf(cpf)))
			throw new Exception("CPF invalido");
		this.cpf = cpf;
	}
	
	/**
	 * Metodo acessador que retorna o telefone de uma pessoa.
	 * @return String telefone
	 */
	public String getTelefone() {
		return telefone;
	}

	/**
	 * Metodo modificador que seta o telefone da Pessoa
	 * 
	 * @param String
	 *            Novo telefone
	 * @return boolean true caso tenha sido atualizado, false caso contrario
	 */
	public void setTelefone(String telefone)throws Exception {
		if (!(Verificador.verificaTelefone(telefone)))
			throw new Exception("Telefone invalido");
		this.telefone = telefone;
	}
	
	/**
	 * Metodo acessador que retorna o email de uma pessoa
	 * @return String email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * Metodo modificador que seta o email da Pessoa
	 * 
	 * @param String
	 *            Novo email
	 * @return boolean true caso tenha sido atualizado, false caso contrario
	 * @throws Exception lancada caso o email seja invalido
	 */
	public void setEmail(String email) throws Exception {
		if (!(Verificador.verificaEmail(email)))
			throw new Exception("Email invalido");
		this.email = email;
	}
	
	/**
	 * Metodo que resgata o sexo de uma pessoa
	 * @return Enum Sexo
	 */
	public Sexo getSexo() {
		return sexo;
	}

	/**
	 * Metodo modificador que seta o sexo da pessoa
	 * 
	 * @param Sexo
	 *            sexo da pessoa
	 * @throws Exception caso o sexo seja invalido
	 */
	public void setSexo(Sexo sexo) throws Exception {
		if (sexo != Sexo.F && sexo != Sexo.M)
			throw new Exception("Sexo invalido");
		this.sexo = sexo;
	}
	
	/**
	 * Metodo acessador que resgata o endereco de uma pessoa
	 * @return String endereco
	 */
	public String getEndereco() {
		return endereco;
	}

	/**
	 * Metodo modificador que seta o endereco da Pessoa
	 * 
	 * @param String
	 *            Novo endereco
	 * @throws Exception caso o endereco seja invalido
	 */
	public void setEndereco(String endereco) throws Exception {
		if (!Verificador.verificaEndereco(endereco))
			throw new Exception("Endereço invalido");
		this.endereco = endereco;
	}
	
	/**
	 * Metodo acessador que retorna a data de nascimento de uma pessoa.
	 * @return Calendar data de nascimento
	 */
	public Calendar getDataDeNascimento() {
		return dataDeNascimento;
	}

	/**
	 * Metodo modificador que seta a data de nascimento da Pessoa
	 * 
	 * @param Calendar
	 *            Nova data
	 * @return boolean true caso tenha sido atualizado, false caso contrario
	 * @throws Exception lancada caso nao passe nos testes do Verificador.
	 */
	public void setDataDeNascimento(Calendar dataDeNascimento) throws Exception {
		if (!Verificador.verificaDataPassada(dataDeNascimento))
			throw new Exception("Data de nascimento invalida");
		this.dataDeNascimento = dataDeNascimento;
		idade = calculaIdade();
	}
	
	/**
	 * Metodo modificador que seta a data de nascimento da Pessoa
	 * @param String data desejada
	 * @throws Exception caso nao passe nos testes do Verificador.
	 */
	public void setDataDeNascimento(String data) throws Exception{
		if (!Verificador.verificaData(data))
			throw new Exception("Data no formato errado");
		Integer dia = Integer.valueOf(data.substring(0, 1));
		Integer mes = Integer.valueOf(data.substring(3, 4));
		Integer ano = Integer.valueOf(data.substring(6, 9));
		Calendar dataNova = new GregorianCalendar(dia, mes, ano);
		setDataDeNascimento(dataNova);
	}
	
	/**
	 * Metodo acessador que resgata a idade de uma pessoa.
	 * @return int idade
	 */
	public int getIdade() {
		return idade;
	}


	/**
	 * Metodo que calcula e retorna a idade da Pessoa
	 * 
	 * @return int idade calculada
	 */
	private int calculaIdade() {
		Calendar diaAtual = new GregorianCalendar();
		Calendar nascimento = getDataDeNascimento();
		return (nascimento.get(Calendar.DAY_OF_YEAR) < diaAtual
				.get(Calendar.DAY_OF_YEAR)) ? diaAtual.get(Calendar.YEAR)
				- nascimento.get(Calendar.YEAR) : diaAtual.get(Calendar.YEAR)
				- nascimento.get(Calendar.YEAR) - 1;
	}
 
	@Override
	public String toString() {
		return "Nome: " + getNome() + "\nCPF: " + getCPF();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Pessoa))
			return false;
		Pessoa pessoa = (Pessoa) obj;
		return pessoa.getCPF().equals(getCPF());
	}

}